/*
 * File name: MenuPlugin.java
 * 
 * Description: TODO
 *
 * Author: Theobald_Wu, contact with wuqizhi@tydtech.com
 * 
 * Date: May 27, 2015  4:36:38 PM
 * 
 * Copyright (C) 2015 Zhouyou Network Technology Co.,Ltd.
 * 
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.freeme.cameraplugin.childrenmode;

import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.freeme.camera.BasePluginImpl;
import com.freeme.camera.CameraInterfaceManage;
import com.freeme.camera.ICameraExt;
import com.freeme.elementscenter.agent.ECOfflineItemData;
import com.freeme.elementscenter.agent.ECOfflineUtil;

import java.io.IOException;
import java.util.List;

public class ChildrenMode extends BasePluginImpl implements MediaPlayer.OnCompletionListener {
    private static final String TAG = "[FREEME]ChildrenMode";
    public static final int FREEME_SCENE_MODE_CHILD_ID = 101;
    public static final int CMD_CAMERA_CLOSE_MODE = 0x010;
    private ViewGroup mListLayout;
    private boolean mShowList;
    private ViewGroup mVoiceSettingList;
    private View mSettingChildRoot;
    private View mSelectedVoiceItem;
    private ViewGroup mRootView;
    private MediaPlayer mVoicePlayer;
    private AudioManager mAudioManager;
    private String mPackageName;
    private int mOrientation = -1;
    private LayoutInflater mInflater;
    private TextView mChildIndicator;
    private TextView mChildIndicatorBack;
    private Drawable mPopDownDrawable;
    private Drawable mPopUpDrawable;
    private SettingDownLoadView mDownloadView;
    private ICameraExt mCameraExt = null;

    public ChildrenMode() {
        super();
    }

    public ChildrenMode(Context c, String pkgName) {
        super(c, pkgName);

        mPackageName = pkgName;
        mVoicePlayer = new MediaPlayer();
        mVoicePlayer.setOnCompletionListener(this);
        mAudioManager = (AudioManager) mHostContext.getSystemService(Context.AUDIO_SERVICE);
        mInflater = LayoutInflater.from(mContext);
        mInflater.setFactory(new LayoutInflater.Factory() {
            @Override
            public View onCreateView(String name, Context context, AttributeSet attrs) {
                if (name.equals("com.freeme.cameraplugin.childrenmode.SettingItemView")) {
                    return new SettingItemView(context, attrs);
                } else if (name.equals("com.freeme.cameraplugin.childrenmode.SettingDownLoadView")) {
                    return new SettingDownLoadView(context, attrs);
                }
                return null;
            }
        });
    }

    @Override
    public int getModuleID() {
        return FREEME_SCENE_MODE_CHILD_ID;
    }

    @Override
    public String getPkgName() {
        return mPackageName;
    }

    @Override
    public Drawable getModuleIcon() {
        return mContext.getResources().getDrawable(R.drawable.entry_icon);
    }

    @Override
    public String getModuleTitle() {
        return mContext.getString(R.string.plugin_name);
    }

    @Override
    public byte[] blendOutput(byte[] jpegData) {
        return null;
    }

    @Override
    public void showPanel(ViewGroup root) {
        mCameraExt = CameraInterfaceManage.getInstance().cameraExt;
        mRootView = root;
        showList();
    }

    @Override
    public void hidePanel() {
        hideList();
    }

    @Override
    public void switchPanel(ViewGroup root) {
        mRootView = root;

        if (mShowList) {
            hideList();
        } else {
            showList();
        }
    }

    @Override
    public void onOrientationChanged(int orientation) {
        /*
         * tydtech:azmohan on: Wed, 16 Dec 2015 11:04:14 +0800 no orientation if
         * (mOrientation != orientation) { Log.i(TAG,
         * "onOrientationChanged(): orientation = " + orientation); mOrientation
         * = orientation; setOrientation(mListLayout, mOrientation, true); }
         */
        // End of tydtech: azmohan
    }

    @Override
    protected void onRelease() {
        mAudioManager.abandonAudioFocus(mAudioFocusListener);
        if (mVoicePlayer != null) {
            stop();
            mVoicePlayer.release();
            mVoicePlayer = null;
        }
        destoryPanel();
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        if (mSelectedVoiceItem != null) {
            mSelectedVoiceItem.setSelected(false);
        }
    }

    private void showList() {
        if (mShowList) {
            return;
        }

        Log.i(TAG, "showList(): Enter");
        if (mListLayout == null) {
            mPopDownDrawable = mContext.getResources().getDrawable(R.drawable.mode_setting_pop_up);
            mPopDownDrawable.setBounds(0, 0, mPopDownDrawable.getIntrinsicWidth(),
                    mPopDownDrawable.getIntrinsicHeight());
            mPopUpDrawable = mContext.getResources().getDrawable(R.drawable.mode_setting_pop_down);
            mPopUpDrawable.setBounds(0, 0, mPopUpDrawable.getIntrinsicWidth(),
                    mPopUpDrawable.getIntrinsicHeight());
            mListLayout = (ViewGroup) mInflater.inflate(
                    mContext.getResources().getLayout(R.layout.children_voice_setting_panel), null);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.MATCH_PARENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
            mRootView.addView(mListLayout, lp);
            mVoiceSettingList = (ViewGroup) mListLayout.findViewById(R.id.item_list);
            mSettingChildRoot = mListLayout.findViewById(R.id.setting_child_root);
            mDownloadView = (SettingDownLoadView) mListLayout.findViewById(R.id.child_download);
            mDownloadView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent("freeme.intent.action.freeme.ec");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intent.putExtra("ec_type_code", ECOfflineUtil.CHILDMODE_TYPE_CODE);
                    mContext.startActivity(intent);
                }
            });
            mChildIndicator = (TextView) mListLayout.findViewById(R.id.mode_button_down);
            mChildIndicatorBack = (TextView) mListLayout.findViewById(R.id.mode_button);
            mChildIndicator.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mSettingChildRoot.getVisibility() == View.VISIBLE) {
                        hideSettingRoot();
                    } else {
                        showSettingRoot();
                    }
                }
            });

            mChildIndicatorBack.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mCameraExt.sendCommand(CMD_CAMERA_CLOSE_MODE);
                }
            });

            createVoiceSettingList();
            addDynimVoiceSettingList();
        }
        showSettingRoot();
        mShowList = true;
        mListLayout.setVisibility(View.VISIBLE);
    }

    public void showSettingRoot() {
        mSettingChildRoot.setVisibility(View.VISIBLE);
        mChildIndicator.setCompoundDrawables(null, null, mPopUpDrawable, null);
    }

    public void hideSettingRoot() {
        mSettingChildRoot.setVisibility(View.GONE);
        mChildIndicator.setCompoundDrawables(null, null, mPopDownDrawable, null);

    }

    private void destoryPanel() {
        if (mRootView != null) {
            int size = mRootView.getChildCount();
            for (int i = 0; i < size; i++) {
                View child = mRootView.getChildAt(i);
                if (child == mListLayout) {
                    mRootView.removeView(child);
                }
            }
        }
        mListLayout = null;
        mShowList = false;
    }

    private void refactor() {
        if (mRootView != null) {
            boolean isShowing = mShowList;
            destoryPanel();
            if (isShowing) {
                showList();
            }
        }
    }

    private void hideList() {
        if (mListLayout == null || !mShowList || mRootView == null) {
            return;
        }
        mRootView.removeView(mListLayout);
        mListLayout.destroyDrawingCache();
        stop();
        mListLayout = null;
        mShowList = false;
    }

    private void createVoiceSettingList() {
        Log.i(TAG, "createVoiceSettingList(): Enter");
        int[] titles = getIds(mContext.getResources(), R.array.pref_child_entries);
        String[] voiceRes = mContext.getResources().getStringArray(R.array.pref_child_entryvalues);
        getIds(mContext.getResources(), R.array.pref_child_icons);
        for (int i = 0; i < titles.length; i++) {
            View view = mInflater.inflate(mContext.getResources().getLayout(R.layout.setting_item),
                    mVoiceSettingList, false);
            SettingItemView settingItem = (SettingItemView) view.findViewById(R.id.item_root);
            settingItem.setText(titles[i]);
            settingItem.showPrompt(false);
            mVoiceSettingList.addView(view);
            // get voice raw id
            int rawId = mContext.getResources().getIdentifier(voiceRes[i], "raw", mPackageName);
            view.setId(rawId);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // play voice by raw id
                    play(v.getId());

                    // restore state of old selected
                    if (mSelectedVoiceItem != null) {
                        mSelectedVoiceItem.setSelected(false);
                    }

                    v.setSelected(true);
                    mSelectedVoiceItem = v;
                }
            });
        }
    }

    private void playByUrl(String url) {
        try {
            mVoicePlayer.reset();
            mVoicePlayer.setDataSource(url); // 设置数据源
            mVoicePlayer.prepare(); // prepare自动播放
            mVoicePlayer.start();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void addDynimVoiceSettingList() {
        List<ECOfflineItemData> itemList = ECOfflineUtil.getOfflineItemDataByType(
                ECOfflineUtil.CHILDMODE_TYPE_CODE, 0);
        for (ECOfflineItemData itemData : itemList) {
            View view = mInflater.inflate(R.layout.setting_item, mVoiceSettingList, false);
            final SettingItemView settingItem = (SettingItemView) view.findViewById(R.id.item_root);
            settingItem.setText(itemData.mName);
            settingItem.showPrompt(false);
            if (ECOfflineUtil.isFileExist(itemData.mItemNewStatusFileFullName)) {
                mVoiceSettingList.addView(view, 0);
                settingItem.showPrompt(true);
            } else {
                mVoiceSettingList.addView(view);
            }
            view.setTag(view.getId(), itemData);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Object obj = v.getTag(v.getId());
                    if (obj != null && obj instanceof ECOfflineItemData) {
                        ECOfflineItemData itemData = (ECOfflineItemData) obj;
                        v.findViewById(R.id.item_root);
                        if (ECOfflineUtil.isFileExist(itemData.mItemNewStatusFileFullName)) {
                            ECOfflineUtil.deleteFile(itemData.mItemNewStatusFileFullName);
                        }
                        playByUrl(itemData.mPrimitiveUrl);
                    }
                    settingItem.showPrompt(false);
                    if (mSelectedVoiceItem != null) {
                        mSelectedVoiceItem.setSelected(false);
                    }

                    v.setSelected(true);
                    mSelectedVoiceItem = v;
                }
            });
        }
    }

    private void stop() {
        if (mVoicePlayer != null && mVoicePlayer.isPlaying()) {
            mVoicePlayer.stop();
            onCompletion(null);
        }
    }

    private void play(int sound) {
        // should reset at first ant then initialize again.
        if (mVoicePlayer == null) {
            mVoicePlayer = new MediaPlayer();
        }
        try {
            mVoicePlayer.reset();
            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(sound);
            if (afd == null) {
                // illegal raw file
                throw new IllegalAccessError();
            }

            mVoicePlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
                    afd.getLength());
            afd.close();
            mVoicePlayer.prepare();
            mVoicePlayer.start();
        } catch (IOException ex) {
            Log.d(TAG, "play failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "play failed:", ex);
            // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "play failed:", ex);
            // fall through
        } catch (NullPointerException ex) {
            Log.d(TAG, "play failed:", ex);
            // fall through
        }
    }

    private int[] getIds(Resources res, int resId) {
        if (resId == 0) return null;

        TypedArray array = res.obtainTypedArray(resId);
        int n = array.length();
        int ids[] = new int[n];
        for (int i = 0; i < n; ++i) {
            ids[i] = array.getResourceId(i, 0);
        }
        array.recycle();

        return ids;
    }

    private void setOrientation(View view, int orientation, boolean animation) {
        if (view == null) {
            return;
        }

        if (view instanceof Rotatable) {
            ((Rotatable) view).setOrientation(orientation, animation);
        } else if (view instanceof ViewGroup) {
            ViewGroup group = (ViewGroup) view;
            for (int i = 0, count = group.getChildCount(); i < count; i++) {
                setOrientation(group.getChildAt(i), orientation, animation);
            }
        }
    }

    private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
        public void onAudioFocusChange(int focusChange) {
            if (focusChange == AudioManager.AUDIOFOCUS_LOSS
                    || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
                stop();
            }
        }
    };
}
